package com.maycur.ctrip.servant;

import Ice.Current;
import com.maycur.ctrip.domain.SimplifiedUser;
import com.maycur.ctrip.dto.*;
import com.maycur.ctrip.service.OrderService;
import com.maycur.ctrip.service.UserService;
import com.maycur.ctrip.util.Constant;
import com.maycur.ice.ctrip.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * Created by JoeyXin on 6/22/16.
 */
@Service
public class CtripService extends _CtripServiceDisp {
    private static final Logger logger = LoggerFactory.getLogger(CtripService.class);
    @Autowired
    private OrderService orderService;

    @Autowired
    private UserService userService;

    @Override
    public CtripOrderDto searchOrdersFromCtrip(String entCode, String userCode, String startDate, String endDate,
        Current __current) {
        logger.info("start to search ctrip order for employee(entCode={}, userCode={}) at period({} -> {}) ", entCode, userCode, startDate, endDate);

        SimplifiedUser user = userService.getUser(entCode, userCode);

        if(user == null || StringUtils.isEmpty(user.geteId())) {
            logger.error("Could not identify user with userCode = {} or his/her employee id was not set!", userCode);
            return null;
        }

        FetchCtripOrderRequest request = new FetchCtripOrderRequest();
        request.seteId(user.geteId());
        request.setDateFrom(startDate);
        request.setDateTo(endDate);
        CtripOrderDto ctripOrderDto = new CtripOrderDto();

        List<ItineraryEntity> itineraryEntityList = orderService.fetchOrdersFromCtrip(entCode, request);
        if(!CollectionUtils.isEmpty(itineraryEntityList)) {
            OrderSearchCriteria orderSearchCriteria = new OrderSearchCriteria(entCode, user.geteId(), startDate, endDate);

            for(ItineraryEntity entity: itineraryEntityList) {
                ctripOrderDto.hotelOrderDtoSeq = convertToHotelOrderDtos(entity.getHotelOrderInfoEntities(), orderSearchCriteria);
                ctripOrderDto.flightOrderDtoSeq = convertToFlightOrderDtos(entity.getFlightOrderInfoEntities(), orderSearchCriteria);
                ctripOrderDto.trainOrderDtoSeq = convertToTrainOrderDtos(entity.getTrainOrderInfoEntities(), orderSearchCriteria);
            }
        }

        return ctripOrderDto;
    }

    private HotelOrderDto[] convertToHotelOrderDtos(List<HotelOrderInfoEntity> hotelOrderInfoEntities, OrderSearchCriteria orderSearchCriteria) {
        if(CollectionUtils.isEmpty(hotelOrderInfoEntities))
            return null;

        List<String> orderIdsInDb = orderService.listHotelOrderIdInDb(orderSearchCriteria);
        HotelOrderDto[] hotelOrderDtos = new HotelOrderDto[hotelOrderInfoEntities.size()];

        for (int i = 0; i < hotelOrderInfoEntities.size(); i++) {
            HotelOrderDto hotelOrderDto = hotelOrderInfoEntities.get(i).convertToOrderDto();
            if (hotelOrderDto != null) {
                if(!CollectionUtils.isEmpty(orderIdsInDb) && orderIdsInDb.contains(hotelOrderDto.orderId)) {
                    hotelOrderDto.maycurSyncedStatus = true;
                }
                hotelOrderDtos[i] = hotelOrderDto;
            }
        }

        return hotelOrderDtos;
    }

    private FlightOrderDto[] convertToFlightOrderDtos(List<FlightOrderInfoEntity> flightOrderInfoEntities, OrderSearchCriteria orderSearchCriteria) {
        if(CollectionUtils.isEmpty(flightOrderInfoEntities))
            return null;

        List<String> orderIdsInDb = orderService.listFlightOrderIdInDb(orderSearchCriteria);
        FlightOrderDto[] flightOrderDtos = new FlightOrderDto[flightOrderInfoEntities.size()];

        for (int i = 0; i < flightOrderInfoEntities.size(); i++) {
            FlightOrderDto flightOrderDto = flightOrderInfoEntities.get(i).convertToOrderDto();
            if (flightOrderDto != null) {
                if(!CollectionUtils.isEmpty(orderIdsInDb) && orderIdsInDb.contains(flightOrderDto.orderId)) {
                    flightOrderDto.maycurSyncedStatus = true;
                }
                flightOrderDtos[i] = flightOrderDto;
            }
        }
        return flightOrderDtos;
    }


    private TrainOrderDto[] convertToTrainOrderDtos(List<TrainOrderInfoEntity> trainOrderInfoEntities, OrderSearchCriteria orderSearchCriteria) {
        if(CollectionUtils.isEmpty(trainOrderInfoEntities))
            return null;
        List<String> orderIdsInDb = orderService.listTrainOrderIdInDb(orderSearchCriteria);
        TrainOrderDto[] trainOrderDtos = new TrainOrderDto[trainOrderInfoEntities.size()];

        for (int i = 0; i < trainOrderInfoEntities.size(); i++) {
            TrainOrderDto trainOrderDto = trainOrderInfoEntities.get(i).convertToOrderDto();
            if (trainOrderDto != null) {
                if(!CollectionUtils.isEmpty(orderIdsInDb) && orderIdsInDb.contains(trainOrderDto.orderId)) {
                    trainOrderDto.maycurSyncedStatus = true;
                }
                trainOrderDtos[i] = trainOrderDto;
            }
        }
        return trainOrderDtos;
    }

    @Override
    public boolean syncCtripOrderToMaycur(String entCode, String userCode, String[] orderIds, Current __current) {
        if(orderIds.length == 0)
            return true;

        String joinedOrderId = StringUtils.join(orderIds, Constant.DELIMITER_COMMA);
        logger.info("start to sync ctrip orders(orderId={}) to Maycur for enterprise(entCode={}) ",
            joinedOrderId, entCode);

        FetchCtripOrderRequest request = new FetchCtripOrderRequest();
        request.setOrderId(joinedOrderId);

        List<ItineraryEntity> itineraryEntityList = orderService.fetchOrdersFromCtrip(entCode, request);

        return orderService.syncItineraryListToMaycur(entCode, userCode, itineraryEntityList);
    }
}
